package com.javasoft.service.LCB;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.javasoft.dao.LCB.UserInfoDao;
import com.javasoft.entity.LCB.UserInfoEntity;
import com.javasoft.util.LCB.DuplicateAccountException;
import com.javasoft.util.LCB.CsvImportUtil;
import org.springframework.stereotype.Service;
import com.javasoft.util.LCB.PasswordEncoderUtil;//导入加密程序
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service("userInfoService")
public  class
UserInfoServiceImpl extends ServiceImpl<UserInfoDao, UserInfoEntity> implements UserInfoService {


    /***
     * 12.29进行对用户新增的时候密码加密，在saveOrUpdate代码部分进行加密过程
     * @param current
     * @param size
     * @param name
     * @return
     */
    @Override
    public Page<UserInfoEntity> page(Integer current, Integer size, String name) {
        LambdaQueryWrapper<UserInfoEntity>wrapper =new LambdaQueryWrapper<>();
        if(!"".equals(name)){
            //精确查询
            //wrapper.eq(UserInfoEntity::getName,name);

            //模糊查询
            wrapper.like(UserInfoEntity::getName,name);
        }

        Page<UserInfoEntity> page =page(new Page<>(
                current,
                size
        ),
                wrapper
        );
        return page;
    }
/// 尝试在这里加入密码加密过程（新增的时候保存密码加密信息）12.30
/// 后续测试成功，能够实现加密功能，但是具体需不需解密过程呢？？？？？
/// 感觉不需要解密过程，符合逻辑
    @Override
    public boolean saveOrUpdateById(UserInfoEntity userInfoEntity) {
        /// 这里是具体的加密部分
        if (userInfoEntity.getPassword()!=null)
        {
            String encodedPassword =PasswordEncoderUtil.encode(userInfoEntity.getPassword());
            userInfoEntity.setPassword(encodedPassword);
        }
        /// 进行查重排除，避免重复的账户被使用导致问题
        LambdaQueryWrapper<UserInfoEntity> checkWrapper =Wrappers.lambdaQuery();
        checkWrapper.eq(UserInfoEntity::getAccount,userInfoEntity.getAccount());
        int count =count(checkWrapper);
        if (count>0)
        {
            throw new DuplicateAccountException("该账号已被注册，请重新输入");
        }


        /// 这里是对用户信息进行保存和新增
        if(userInfoEntity.getId()!= null){
            return updateById(userInfoEntity);

        }
        else{
            return save(userInfoEntity);
        }

    }//完成新增与保存

    @Override
    public boolean deleteBacthIds(List<Integer> ids) {
        return removeByIds(ids);//完成批量基于id的删除方法
    }
/// /////////12.29create ,debug at afternoon,下午已经完成更改测试，nice没问题!!!!!
    @Override
    public boolean deleteBatchByNames(List<String> names) {
        return removeByNames(names);
    }

    private boolean removeByNames(List<String> names) {
        if (names == null ||names.isEmpty()){
            return false;//如果传入的用户名列表是空的表，那么返回false
        }
        LambdaQueryWrapper<UserInfoEntity>wrapper =Wrappers.lambdaQuery() ;
        wrapper.in(UserInfoEntity::getName,names);//构建in条件，看看是否存在已在的列表中
        return remove(wrapper);//根据已知条件删除记录


    }//完成基于name的删除

    /// 下面写一个批量导入功能，主要是想尝试在postman中能够实现12.30晚
    /**
     * 批量导入用户信息
     * @param file CSV 文件流
     * @return 是否成功导入
     */
    @Override
    public boolean batchImportByFile(MultipartFile file) {
        try (InputStreamReader reader = new InputStreamReader(file.getInputStream(), StandardCharsets.UTF_8)) {
            List<UserInfoEntity> users = CsvImportUtil.parseCsv(reader);

            // 获取现有账户集合
            Set<String> existingAccounts = getExistingAccounts();
            for (UserInfoEntity user : users) {
                if (existingAccounts.contains(user.getAccount())) {
                    System.out.println("用户重复: " + user.getAccount() + ". 跳过该用户");
                    continue; // 跳过重复的账户
                }

                if (!saveOrUpdateById(user)) {
                    return false; // 如果任何一个用户保存失败，则返回false
                }
            }
            return true; // 所有用户都保存成功
        } catch (Exception e) {
            e.printStackTrace();
            return false; // 发生异常时返回false
        }
    }
/// 基于Json形式的postman测试用例多个单词条数据批量导入的实现
/// 终于——12.31晚上样例测试成功。功能实现o(*￣▽￣*)ブ😊
    @Override
    public boolean batchImportByJson(UserInfoEntity userInfoEntity) {
        if (userInfoEntity == null) {
            return false; // 如果用户实体为空，返回false
        }
        // 获取现有账户集合
        Set<String> existingAccounts = getExistingAccounts();
        if (existingAccounts.contains(userInfoEntity.getAccount())) {
            System.out.println("该用户名已被使用: " + userInfoEntity.getAccount() + ".跳过该用户.");
            return false; // 跳过重复的账户
        }

        try {
            return saveOrUpdateById(userInfoEntity); // 调用保存或更新方法
        } catch (Exception e) {
            e.printStackTrace();
            return false; // 如果发生异常，返回false
        }
    }

    /***
     * 这里实现用户的登陆匹配功能，但是没有前端
     * @param account
     * @param password
     * @return
     */
    @Override
    public boolean login(String account, String password) {
        if (account == null || password == null) {
            return false; // 如果账号或密码为空，返回false
        }

        // 查询数据库中是否存在相同账号和密码的用户，不能有用户名重复的用户
        LambdaQueryWrapper<UserInfoEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserInfoEntity::getAccount, account);
        UserInfoEntity user = getOne(wrapper);

        if (user != null && PasswordEncoderUtil.matches(password, user.getPassword())) {
            return true; // 密码匹配，登录成功
        }

        return false; // 密码不匹配或用户不存在，登录失败
    }

    @Override/// 实现该查重方法
    public Set<String> getExistingAccounts() {
        LambdaQueryWrapper<UserInfoEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(UserInfoEntity::getAccount);
        List<UserInfoEntity> userList = list(wrapper);

        Set<String> accountsSet = new HashSet<>();
        for (UserInfoEntity user : userList) {
            accountsSet.add(user.getAccount());
        }

        return accountsSet;
    }

    // 添加 matches 方法
    public static boolean matches(String rawPassword, String encodedPassword) {
        return PasswordEncoderUtil.encode(rawPassword).equals(encodedPassword);
    }

/// /////////
/// 下面是老师带着写的一些代码，emm完全用不上（但是还不能删掉，删掉会报错
/// 报错信息说我的ServiceImpl不是抽象的并不能覆盖Service中的抽象方法page
/// emmm那就只能保留它在这个代码的最底部了o.O （
/// 就这样吧
/**
    @Override
    public Integer add(UserInfoEntity userInfo) {

        return baseMapper.insert(userInfo);
    }

    @Override
    public IPage<UserInfoEntity> page(UserInfoEntity userInfo,int page,int pageline){
        LambdaQueryWrapper<UserInfoEntity> query= Wrappers.lambdaQuery();
        query.eq(UserInfoEntity::getUserClass,userInfo.getUserClass());
        //分页参数
        if(page==0){
            page=1;
        }
        if (pageline==0){
            pageline=10;
        }
        IPage<UserInfoEntity>ipage= Page.of(page,pageline);


        return baseMapper.selectPage(ipage,query);
    }
    **////
}
